/*
**************************************************************************************************************
    @brief          : libspi库测试demo
    @author         : xiongjinqi
    @date           : 2024/08/08
**************************************************************************************************************
*/
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <sched.h>
#include <assert.h>
#include <signal.h>
#include <time.h>
#include <stdint.h>
#include <unistd.h>
#include <getopt.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <linux/types.h>
#include <linux/spi/spidev.h>
#include <sys/time.h>

#include "datatype.h"
#include "spi_protocol.h"

#define DEBUG                           printf
#define _STRING(x)                      #x
#define STR(s)                          _STRING(s)
#define _SENSORID_GET(name, sensor)     (ID_##name##_##sensor)
#define SENSORID_GET(name, sensor)      _SENSORID_GET(name, sensor)

typedef enum {
    INDEX_ZJB_28V_JCXJ    = 0,
    INDEX_ZJB_12V_WAOXJ   ,
    INDEX_ZJB_28V_BQXJ    ,
    INDEX_ZJB_12V_DYGY_B  ,
    INDEX_ZJB_28V_FFXJ    ,
    INDEX_ZJB_12V28V_BF1  ,
    INDEX_ZJB_12V28V_BF2  ,
    INDEX_ZJB_28V_TSGY    ,
    INDEX_ZJB_28V_QGSJ    ,
    INDEX_ZJB_12V28V_HJJC1,
    INDEX_ZJB_12V28V_HJJC2,
    INDEX_ZJB_12V28V_HJJC3,
    INDEX_ZJB_12V_GSDJ1   ,
    INDEX_ZJB_12V_GSDJ2   ,
    INDEX_ZJB_12V_XGHTM   ,
    INDEX_ZJB_28V_KF      ,
}_ZJB_POWER_ONOFF_INDEX;

char *ZJB_POWER_NAME[] = {
    "ZJB_28V_JCXJ    ",
    "ZJB_12V_WAOXJ   ",
    "ZJB_28V_BQXJ    ",
    "ZJB_12V_DYGY_B  ",
    "ZJB_28V_FFXJ    ",
    "ZJB_12V28V_BF1  ",
    "ZJB_12V28V_BF2  ",
    "ZJB_28V_TSGY    ",
    "ZJB_28V_QGSJ    ",
    "ZJB_12V28V_HJJC1",
    "ZJB_12V28V_HJJC2",
    "ZJB_12V28V_HJJC3",
    "ZJB_12V_GSDJ1   ",
    "ZJB_12V_GSDJ2   ",
    "ZJB_12V_XGHTM   ",
    "ZJB_28V_KF      ",
};

u8 zjb_sensor_id[] = {
    ID_ZJB_FAN1,
    ID_ZJB_FAN2,
    ID_ZJB_FAN3,
    ID_ZJB_FAN4,
    ID_ZJB_TEMPRETURE,
    ID_ZJB_28V_JCXJ,
    ID_ZJB_12V_WAOXJ,
    ID_ZJB_28V_BQXJ,
    ID_ZJB_12V_DYGY_B,
    ID_ZJB_28V_FFXJ,
    ID_ZJB_12V28V_BF1,
    ID_ZJB_12V28V_BF2,
    ID_ZJB_28V_TSGY,
    ID_ZJB_28V_QGSJ,
    ID_ZJB_12V28V_HJJC1,
    ID_ZJB_12V28V_HJJC2,
    ID_ZJB_12V28V_HJJC3,
    ID_ZJB_12V_GSDJ1,
    ID_ZJB_12V_GSDJ2,
    ID_ZJB_12V_XGHTM,
    ID_ZJB_28V_KF,
    ID_ZJB_HALL_GSDJ1,
    ID_ZJB_HALL_GSDJ2,
};



void usage_print(char *filename)
{
    DEBUG("Usage: %s [options] [sensorid] \r\n", filename);
    DEBUG("\tOptions:\r\n");
    DEBUG(" \t -c \t CMD name, contain of 11 / 22 / 23\r\n");
    DEBUG(" \t\t cmd11 no parameters\r\n");
    DEBUG(" \t\t cmd22 has board name, sensor id, set value\r\n");
    DEBUG(" \t\t cmd23 has ipmi bus name\r\n");

    DEBUG(" \t -b \t board name, contain of ZJB  \r\n");

    DEBUG(" \t -bus \t ipmi bus , contain of as following \r\n");
    DEBUG(" \t\t 1 meaning ipmi bus1 \r\n");
    DEBUG(" \t\t 2 meaning ipmi bus2 \r\n");

    DEBUG(" \t -p \t config power off(default POWER ON), contain of as following \r\n");
    DEBUG(" \t\t                          \n \
            \t\t 0-ZJB_28V_JCXJ     \n \
            \t\t 1-ZJB_12V_WAOXJ    \n \
            \t\t 2-ZJB_28V_BQXJ     \n \
            \t\t 3-ZJB_12V_DYGY_B   \n \
            \t\t 4-ZJB_28V_FFXJ     \n \
            \t\t 5-ZJB_12V28V_BF1   \n \
            \t\t 6-ZJB_12V28V_BF2   \n \
            \t\t 7-ZJB_28V_TSGY     \n \
            \t\t 8-ZJB_28V_QGSJ     \n \
            \t\t 9-ZJB_12V28V_HJJC1 \n \
            \t\t 10-ZJB_12V28V_HJJC2\n \
            \t\t 11-ZJB_12V28V_HJJC3\n \
            \t\t 12-ZJB_12V_GSDJ1   \n \
            \t\t 13-ZJB_12V_GSDJ2   \n \
            \t\t 14-ZJB_12V_XGHTM   \n \
            \t\t 15-ZJB_28V_KF      \r\n");

    DEBUG(" \t -s \t sensor id, contain of as following \r\n");
    DEBUG("\n\t\t\t 0-FAN1         \n    \
           \t\t 1-FAN2         \n    \
           \t\t 2-FAN3         \n    \
           \t\t 3-FAN4         \n    \
           \t\t 4-TEMPRETURE   \n    \
           \t\t 5-28V_JCXJ     \n    \
           \t\t 6-12V_WAOXJ    \n    \
           \t\t 7-28V_BQXJ     \n    \
           \t\t 8-12V_DYGY_B   \n    \
           \t\t 9-28V_FFXJ     \n    \
           \t\t 10-12V28V_BF1   \n    \
           \t\t 11-12V28V_BF2   \n    \
           \t\t 12-28V_TSGY     \n    \
           \t\t 13-28V_QGSJ     \n    \
           \t\t 14-12V28V_HJJC1 \n    \
           \t\t 15-12V28V_HJJC2 \n    \
           \t\t 16-12V28V_HJJC3 \n    \
           \t\t 17-12V_GSDJ1    \n    \
           \t\t 18-12V_GSDJ2    \n    \
           \t\t 19-12V_XGHTM    \n    \
           \t\t 20-28V_KF \r\n");
    DEBUG("\t\t set value maybe <ON>/<OFF> <1>/<2>/<3>/<4> \r\n");
}

u64 time_getms()
{
    struct timeval now;
    gettimeofday(&now, NULL);

    return (now.tv_sec*1000 + now.tv_usec/1000);
}

/*
    usage:
        ./demo cmdxx board_name sensorid 

    example:
        ./demo -c 11
        ./demo -c 12
        ./demo -c 13
        ./demo -c 22 -b ZJB -s sensorid  ON/OFF/1,2,3,4
        ./demo -c 23 -bus 1
        ./demo -c 25 -p 0
*/
int main(int argc, char* argv[])
{
    int ret = 0,index = 0;
    int cmd = 0, bus = 0, setval = 0, sensor_id = 0, power_onoff = 0;
    char *board_name;
    u64 start_time = 0, end_time = 0;

    switch(argc)
    {
        case 3:
        break;
        case 5:
        break;
        case 8:
        break;
        default:
            DEBUG("argc : %d \r\n", argc);
            usage_print(argv[0]);  // 
            return -1;
        break;
    }
    /* 1、第一步初始化 */
    DEBUG("open spi device \r\n");
    spi_protocol_init(&spi_protocol);

    if(argc == 3)   // cmd11
    {
        if(strcmp(argv[1], "-c") == 0) 
        {
            cmd = atoi(argv[2]);
        }
    }

    if(argc == 5)   // cmd23
    {
        if(strcmp(argv[1], "-c") == 0) 
        {
            cmd = atoi(argv[2]);
        }

        if(strcmp(argv[3], "-bus") == 0)
        {
            bus = atoi(argv[4]);
        }

        if(strcmp(argv[3], "-p") == 0)
        {
            power_onoff = atoi(argv[4]);
        }
    }

    if(argc == 8)   // cmd22
    {
        if(strcmp(argv[1], "-c") == 0)
        {
            cmd = atoi(argv[2]);
        }

        if(strcmp(argv[3], "-b") == 0)
        {
            board_name = argv[4];
        }

        if(strcmp(argv[5], "-s") == 0)
        {
            sensor_id = atoi(argv[6]);
        }
    
        if(strcmp(argv[7], "ON") == 0 )
        {
            setval = POWER_ON;
        }
        else
        {
            if(strcmp(argv[7], "OFF") == 0)
                setval = POWER_OFF;
            else
                setval = atoi(argv[7]);
        }
    }

    /* 2、第二步执行相关指令 */
/*-------------------------------------------------------------------------------------*/
    if(cmd == 11)
    {
        start_time = time_getms();
        ret = do_reqcmd11(&spi_protocol);
        end_time = time_getms();
        DEBUG("Line%d : cmd11 execute time : %llu ms\n", __LINE__, end_time - start_time);
        if(ret == 0)
            DEBUG("Line%d : cmd11 success\n", __LINE__);
        else
            DEBUG("Line%d : cmd11 failed\n", __LINE__);
    }
/*-------------------------------------------------------------------------------------*/
    if(cmd == 12)
    {
        start_time = time_getms();
        ret = do_reqcmd12(&spi_protocol);
        end_time = time_getms();
        DEBUG("Line%d : cmd12 execute time : %llu ms\n", __LINE__, end_time - start_time);

        if(ret == 0)
            DEBUG("Line%d : cmd12 success\n", __LINE__);
        else
            DEBUG("Line%d : cmd12 failed\n", __LINE__);
    }
/*-------------------------------------------------------------------------------------*/
    if(cmd == 13)
    {
        int array_size = sizeof(zjb_power_ctrl_get)/sizeof(zjb_power_ctrl_get[0]);
        start_time = time_getms();
        ret = do_reqcmd13(&spi_protocol);
        end_time = time_getms();
        DEBUG("Line%d : cmd13 execute time : %llu ms\n", __LINE__, end_time - start_time);

        if(ret == 0)
        {
            DEBUG("Line%d : cmd13 success\n", __LINE__);
            // CMD13后续用法如下：
            DEBUG("Line%d : prase data package......\n", __LINE__);
            for(index = 0; index<array_size; index++)
            {
                DEBUG("File %s Line%d : name[%s] : onoff_ctrl[%d]\n", __FILE__, __LINE__, ZJB_POWER_NAME[index], zjb_power_ctrl_get[index].onoff_ctrl);
            }
        }
        else
            DEBUG("Line%d : cmd13 failed\n", __LINE__);
    }
/*-------------------------------------------------------------------------------------*/
    if(cmd == 23)//切换ipmi总线
    {
        start_time = time_getms();
        ret = do_reqcmd23(&spi_protocol, bus);
        end_time = time_getms();
        DEBUG("Line%d : cmd23 execute time : %llu ms\n", __LINE__, end_time - start_time);

        if(ret == 0)
            DEBUG("Line%d : cmd23 success\n", __LINE__);
        else
            DEBUG("Line%d : cmd23 failed\n", __LINE__);
    }
/*-------------------------------------------------------------------------------------*/
    u8 onoff[16] = {0};
    onoff[INDEX_ZJB_28V_JCXJ    ] = POWER_ON;
    onoff[INDEX_ZJB_12V_WAOXJ   ] = POWER_ON;
    onoff[INDEX_ZJB_28V_BQXJ    ] = POWER_ON;
    onoff[INDEX_ZJB_12V_DYGY_B  ] = POWER_ON;
    onoff[INDEX_ZJB_28V_FFXJ    ] = POWER_ON;
    onoff[INDEX_ZJB_12V28V_BF1  ] = POWER_ON;
    onoff[INDEX_ZJB_12V28V_BF2  ] = POWER_ON;
    onoff[INDEX_ZJB_28V_TSGY    ] = POWER_ON;
    onoff[INDEX_ZJB_28V_QGSJ    ] = POWER_ON;
    onoff[INDEX_ZJB_12V28V_HJJC1] = POWER_ON;
    onoff[INDEX_ZJB_12V28V_HJJC2] = POWER_ON;
    onoff[INDEX_ZJB_12V28V_HJJC3] = POWER_ON;
    onoff[INDEX_ZJB_12V_GSDJ1   ] = POWER_ON;
    onoff[INDEX_ZJB_12V_GSDJ2   ] = POWER_ON;
    onoff[INDEX_ZJB_12V_XGHTM   ] = POWER_ON;
    onoff[INDEX_ZJB_28V_KF      ] = POWER_ON;
    onoff[power_onoff] = POWER_OFF;
    if(cmd == 25)
    {
        start_time = time_getms();
        ret = do_reqcmd25(&spi_protocol, onoff, 16);
        end_time = time_getms();
        DEBUG("Line%d : cmd25 execute time : %llu ms\n", __LINE__, end_time - start_time);

        if(ret == 0)
            DEBUG("Line%d : cmd25 success\n", __LINE__);
        else
            DEBUG("Line%d : cmd25 failed\n", __LINE__);
    }
/*-------------------------------------------------------------------------------------*/
    if(cmd == 22)
    {
        DEBUG("CTRL: board %s\n", board_name);
        start_time = time_getms();
        ret = do_reqcmd22(&spi_protocol, zjb_sensor_id[sensor_id], setval);
        end_time = time_getms();
        DEBUG("Line%d : cmd22 execute time : %llu ms\n", __LINE__, end_time - start_time);

        if(ret == 0)
            DEBUG("Line%d : cmd22 success\n", __LINE__);
        else
            DEBUG("Line%d : cmd22 failed\n", __LINE__);
    }
/*-------------------------------------------------------------------------------------*/
    #if 0
    static int count = 0;
    while (1)
    {
        //do_reqcmd11(&spi_protocol);
        DEBUG("Running %d\r\n", count++);
        sleep(1);
        // if(count > 10)
        //     break;
    }
    #endif

    /* 第3步释放相关资源 */
    spi_protocol_close(&spi_protocol);
    
    exit(0);
    return 0;
}




